// =================================================================================================
//
//	CopyEngine Framework
//	Copyright 2012 Eran. All Rights Reserved.
//
//	This program is free software. You can redistribute and/or modify it
//	in accordance with the terms of the accompanying license agreement.
//
// =================================================================================================

package copyengine.utils.packerbox
{
	import flash.display.BitmapData;
	import flash.utils.Dictionary;

	import copyengine.utils.packerbox.box.ICEPackerBox;
	import copyengine.utils.packerbox.box.CEPackerBoxConfig;
	import copyengine.utils.packerbox.box.CEPackerBoxPixel;
	import copyengine.utils.packerbox.data.CEPackerElementData;

	public final class CEPackerBuilder
	{
		private var mAllPackerBoxVector:Vector.<ICEPackerBox>;

		/**
		 *生成的箱子的名称前缀,PackerBuilder会尝试生成一系列的箱子,命名如下:
		 * "mPackerBoxNamePR_1","mPackerBoxNamePR_2","mPackerBoxNamePR_3"....
		 */
		private var mPackerBoxNamePR:String;

		private var mCurrentUnPackerElementVector:Vector.<CEPackerElementData>;

		private var mCurrentBox:ICEPackerBox;

		public function CEPackerBuilder()
		{
		}


		//============================================//
		//==Initialize&Dispose  Function
		//============================================//

		/**
		 * @param _allBitmapDataDic				BitmapDataDic的结构(Key->名称,Value->图像)
		 * @param _packerBoxNamePR			箱子的前缀名
		 * 																PackerBuilder会尝试生成一系列的箱子,命名如下:
		 * 																"mPackerBoxNamePR_1","mPackerBoxNamePR_2","mPackerBoxNamePR_3"....
		 */
		public function initialize(_allBitmapDataDic:Dictionary, _packerBoxNamePR:String):void
		{
			mPackerBoxNamePR=_packerBoxNamePR;
			mCurrentUnPackerElementVector=new Vector.<CEPackerElementData>();
			mAllPackerBoxVector=new Vector.<ICEPackerBox>();

			for (var bitmapDataName:String in _allBitmapDataDic)
			{
				var bitmapData:BitmapData=_allBitmapDataDic[bitmapDataName];

				var data:CEPackerElementData=new CEPackerElementData();
				data.bitmapData=bitmapData;
				data.bitmapDataName=bitmapDataName;
				mCurrentUnPackerElementVector.push(data);
			}
		}

		public function dispose():void
		{
			mCurrentUnPackerElementVector=null;
			mAllPackerBoxVector=null;
		}

		//============================================//
		//==Public Interface  Function
		//============================================//

		/**
		 *开始Packer所有Element
		 */
		public function startPackData():void
		{
			//有可能存在length=0情况(比如元件内部只有PH和Textfiled)
			if (mCurrentUnPackerElementVector.length > 0)
			{
				mCurrentUnPackerElementVector.sort(sortElementByMaxSize);
				mCurrentBox=getNewBox();
				packRestElement();

				//尝试缩小当前Box的大小
				for (var i:int=0; i < mAllPackerBoxVector.length; i++)
				{
					mAllPackerBoxVector[i].tryToNarrowDownBox();
				}
			}
		}

		public function getAllPackerBoxVector():Vector.<ICEPackerBox>  { return mAllPackerBoxVector; }

		//========================//
		//==Private  Function
		//=========================//

		private function packRestElement():void
		{
			while (mCurrentUnPackerElementVector.length > 0)
			{
				var isCanFindOneElementFit:Boolean=false;
				var length:int=mCurrentUnPackerElementVector.length;
				for (var i:int=length - 1; i >= 0; i--)
				{
					isCanFindOneElementFit=mCurrentBox.tryToAddToBox(mCurrentUnPackerElementVector[i]);
					if (isCanFindOneElementFit)
					{
						mCurrentUnPackerElementVector.splice(i, 1);
						break;
					}
				}
				if (!isCanFindOneElementFit)
				{
					mAllPackerBoxVector.push(mCurrentBox);
					mCurrentBox=getNewBox();
				}
			}
			//把最后一个Box也存进去
			mAllPackerBoxVector.push(mCurrentBox);
		}


		/**
		 * 根据当前最大的(最宽或最长)元素取其近似的2的幂 来创建一个Box
		 * 如果当前最大的元素大小小于DEFAULT_BOX_SIZE 则创建一个DEFAULT_BOX_SIZE大小的Box
		 *
		 * ！！！注意, 如果选择一个元素创建Box,则会首先把该元素Push到Box中然后再返回
		 *
		 */
		private function getNewBox():ICEPackerBox
		{
			var element:CEPackerElementData=mCurrentUnPackerElementVector.pop();

			var box:ICEPackerBox=new CEPackerBoxPixel();

			var maxSize:int=Math.max(element.bitmapData.width, element.bitmapData.height);
			if (maxSize > CEPackerBoxConfig.DEFAULT_BOX_SIZE)
			{
				box.initialize(CEPackerUtils.getNextPowerOfTwo(maxSize), mPackerBoxNamePR + "_" + (mAllPackerBoxVector.length + 1));
			}
			else
			{
				box.initialize(CEPackerBoxConfig.DEFAULT_BOX_SIZE, mPackerBoxNamePR + "_" + (mAllPackerBoxVector.length + 1));
			}
			box.tryToAddToBox(element);
			return box;
		}


		private function sortElementByMaxSize(_a:CEPackerElementData, _b:CEPackerElementData):int
		{
			var maxSizeA:int=Math.max(_a.bitmapData.width, _a.bitmapData.height);
			var maxSizeB:int=Math.max(_b.bitmapData.width, _b.bitmapData.height);

			//保证所有都绝对有序
			if (maxSizeA == maxSizeB)
			{
				return _a.bitmapDataName > _b.bitmapDataName ? 1 : -1;
			}
			else
			{
				return maxSizeA > maxSizeB ? 1 : -1;
			}
		}


	}
}
